/*
 *  hyperelastic.h
 *  EPPI-0.0
 *
 *  Created by Sergio Conde Martín on 1/04/11.
 *
 */
 
#ifndef _hyperelasticstretches_h_
#define _hyperelasticstretches_h_

#include <iostream>
#include "MATERIALS/material.h"

using namespace std;

class HyperelasticStretches : public Material
{
public:

	double lambda1;		// Elongation on first direction
	double lambda2;		// Elongation on second direction
	double lambda3;		// Elongation on third direction

	double lambda1m;	// Modified Elongation on first direction
	double lambda2m;	// Modified Elongation on second direction
	double lambda3m;	// Modified Elongation on third direction
	
	// double W;	// Strain Energy
	double W1;	// First derivative of Strain Energy respect to the first square stretch (lambda1^2)
	double W2;	// First derivative of Strain Energy respect to the second square stretch (lambda2^2)
	double W3;	// First derivative of Strain Energy respect to the third square stretch (lambda3^2)
	double W11;	// Second derivative of Strain Energy respect to the first square stretch (lambda1^2)
	double W12;	// Second derivative of Strain Energy respect to the first square stretch (lambda1^2)
	double W13;	// Second derivative of Strain Energy respect to the first square stretch (lambda1^2)
	double W22;	// Second derivative of Strain Energy respect to the first square stretch (lambda1^2)
	double W23;	// Second derivative of Strain Energy respect to the first square stretch (lambda1^2)
	double W33;	// Second derivative of Strain Energy respect to the first square stretch (lambda1^2)
	
    double Wvol;	// Volumetric Strain Energy function which depends on the volume ratio J
	
	double dWvol;	// First derivative of Strain Energy respect to the volume ratio J
	double ddWvol;	// Second derivative of Strain Energy respect to the volume ratio J
	
	//double Wiso;	// Isochoric Strain Energy function which depends on the modified right Cauchy-Green tensor: Cm
	
	double Wiso1;	// First derivative of Isochoric Strain Energy respect to the first modified stretch
	double Wiso2;	// First derivative of Isochoric Strain Energy respect to the second modified stretch
	double Wiso3;	// First derivative of Isochoric Strain Energy respect to the third modified stretch
	
	double Wiso11;	// Second derivative of Isochoric Strain Energy respect to the first invariant
	double Wiso12;	// Second crossed derivative of Isochoric Strain Energy respect to the first modified invariant and to the second modified invariant
	double Wiso13;
	double Wiso22;	// Second derivative of Isochoric Strain Energy respect to the second invariant
	double Wiso23;
	double Wiso33;
	
    // Viscoelasticity Tensor
    double kappa11, kappa12, kappa21, kappa22, kappa31, kappa32, kappa41, kappa42;
    double Wiso111, Wiso112, Wiso122;
    double Wiso222, Wiso221, Wiso211;

private:

	double S1;
	double S2;
	double S3;
	
	double Siso1;
	double Siso2;
	double Siso3;
	
	double Siso11;
	double Siso12;
	double Siso13;
	double Siso21;
	double Siso22;
	double Siso23;
	double Siso31;
	double Siso32;
	double Siso33;
	
	double Siso11m;
	double Siso12m;
	double Siso13m;
	double Siso21m;
	double Siso22m;
	double Siso23m;
	double Siso31m;
	double Siso32m;
	double Siso33m;
	
	Vector3d stretches;
	Matrix3d ppaldirecctions;
	
	Vector3d N1;	// First principal direction
	Vector3d N2;	// Second principal direction
	Vector3d N3;	// Third principal direction
	
	VectorXd N1N1;
	VectorXd N2N2;
	VectorXd N3N3;
	
	VectorXd N1N2;
	VectorXd N1N3;
	VectorXd N2N1;
	
	VectorXd N2N3;
	VectorXd N3N1;
	VectorXd N3N2;
	
	Matrix3d SMat;
	Matrix3d SvolMat;
	Matrix3d SisoMat;
	
public:
	HyperelasticStretches();
	HyperelasticStretches(const string&, const string &);
	~HyperelasticStretches(){};
	
	// Virtual functions from base 
	
	void calcInvariants( const VectorXd & );

	void calcW( const VectorXd & );
	
	// Second derivative of Strain Energy for 1D element (Trusses)
	double getDDW( const VectorXd & );
	
	void calcS( const VectorXd & );	// Computes the Second Piola-Kirchoff Stress Tensor
	void calcSvol( const VectorXd & );	// Computes the volumetric part of the Second Piola-Kirchoff Stress Tensor
	void calcSiso( const VectorXd & );	// Computes the isochoric part of the Second Piola-Kirchoff Stress Tensor

	void calcCt( const VectorXd & );

	void calcCTensor( const VectorXd &);
    void calcCiTensor( const VectorXd &);
    void calcP( const VectorXd &);
    void calcPt( const VectorXd &);
    void calctildeP( const VectorXd &);
		
	/** Local functions */
	
	void calcStretches( const VectorXd & );
		
	/** Virtual functions defined in the materials */
	
	virtual void strainEnergy()=0;		// Strain energy
	virtual void DstrainEnergy()=0;		// First derivative of Strain energy respect to the square stretches
	virtual void DDstrainEnergy()=0;	// Second derivative of Strain energy respect to the square stretches
    virtual void DDDstrainEnergy()=0;	// Third derivative of Strain energy respect to the square stretches
	
	virtual vector < double > getvMu(){};
	virtual vector < double > getvAlpha(){};
};

#endif
